#version 150 core

const float pi = 3.14159;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projMatrix;
uniform mat4 textureMatrix;
uniform mat4 shadowMatrix;
uniform float waterHeight;
uniform float time;
uniform int numWaves;
uniform float amplitude[8];
uniform float wavelength[8];
uniform float speed[8];
uniform vec2 direction[8];

in vec3 position;
in vec4 colour;
in vec2 texCoord;

out Vertex {
	vec4 colour;
	vec2 texCoord;
	vec3 normal;
	vec3 worldPos;
	float depth;
	vec4 shadowProj;
} OUT;

float wave(int i, float x, float y) {
    float frequency = 2*pi/wavelength[i];
    float phase = speed[i] * frequency;
    float theta = dot(direction[i], vec2(x, y));
    return amplitude[i] * sin(theta * frequency + time * phase);
}

float waveHeight(float x, float y) {
    float height = 0.0;
    for (int i = 0; i < numWaves; ++i)
        height += wave(i, x, y);
    return height;
}

float dWavedx(int i, float x, float y) {
    float frequency = 2*pi/wavelength[i];
    float phase = speed[i] * frequency;
    float theta = dot(direction[i], vec2(x, y));
    float A = amplitude[i] * direction[i].x * frequency;
    return A * cos(theta * frequency + time * phase);
}

float dWavedy(int i, float x, float y) {
    float frequency = 2*pi/wavelength[i];
    float phase = speed[i] * frequency;
    float theta = dot(direction[i], vec2(x, y));
    float A = amplitude[i] * direction[i].y * frequency;
    return A * cos(theta * frequency + time * phase);
}

vec3 waveNormal(float x, float y) {
    float dx = 0.0;
    float dy = 0.0;
    for (int i = 0; i < numWaves; ++i) {
        dx += dWavedx(i, x, y);
        dy += dWavedy(i, x, y);
    }
    vec3 n = vec3(-dx, 1.0, -dy);
    return normalize(n);
}

void main(void) {
	OUT.colour = colour;
	OUT.texCoord = (textureMatrix * vec4(texCoord , 0.0, 1.0)).xy;
	
	/*if(waterHeight-position.y<20){
		for (int i = 0; i < numWaves; ++i) {
			amplitude[i]*=5.5f;
		}
	}*/
	
	//amplitude[0]+=1.5f
	//if(!position.y>waterHeight+10){
		//discard;
		mat3 normalMatrix = transpose(inverse(mat3(modelMatrix)));
		
		
		
		vec3 pos = (modelMatrix * vec4(position.x, waterHeight, position.z ,1)).xyz;
		
		
		
		vec3 waven = waveNormal(pos.x, pos.z);
		OUT.normal = normalize(normalMatrix * normalize(waven));
		
		float waveH = waveHeight(pos.x, pos.z);
		pos.y = waterHeight + waveH;
		
		OUT.depth = waterHeight-position.y + waveH;
		
		OUT.shadowProj = (shadowMatrix * vec4(position+(normal*1.5),1));
		
		OUT.worldPos = pos;
		gl_Position = (projMatrix * viewMatrix * modelMatrix) * 
					   vec4(pos , 1.0);	   
	//}
			   
}